import { any } from "../../../core/logic";
import { color } from "../../../core/color";
import { Engine } from "../../../Engine";
import { Pass } from "../Pass";
import { Effect, EffectType } from "./Effect";
import { bloom_vert } from "./shaders/bloom_vert";
import { bright_frag, merge_frag, getBlurFragment, composite_frag, blend_frag } from "./shaders/bloom_frag";
import { Register } from "../../../register/Register";
import { ComponentType } from "../../../component/Component";
/**
 * 发光
 * @class
 * @memberof w.effects
 */
class Bloom extends Effect {
  /**
   * @constructor
   * @param {*} opts
   * @param {Number} opts.blurColor 缺省值#cccccc,模糊颜色。
   * @param {Number} opts.blurIntensity 缺省值0.0,模糊强度。
   */
  constructor(opts = {}) {
    super(opts);
    this.type = EffectType.Blur;
    this.sampler = Engine.instance.device.createSampler({
      magFilter: "linear", //nearest linear
      minFilter: "linear",
    });
    this.createMergePipeline()
    this.kernelSizeArray = [3, 5, 7, 9, 11];
    this.resolution = any(opts.resolution, { x: Engine.instance.size[0], y: Engine.instance.size[1] });
    this.nMips = 5;
    this.init()
    this.luminosityThreshold = any(opts.luminosityThreshold, 0.1);
    this.smoothWidth = any(opts.smoothWidth, 0.5);
    this.strength = any(opts.strength, 1);
    this.radius = any(opts.radius, 0.1);
  }
  get strength() {
    return this._strength;
  }

  set strength(v) {
    this._strength = v;
    Engine.instance.queue.writeBuffer(
      this.compositePipeline.bloomStrengthBuffer,
      0,
      new Float32Array([v])
    );
    this.update();
  }
  get radius() {
    return this._radius;
  }

  set radius(v) {
    this._radius = v;
    Engine.instance.queue.writeBuffer(
      this.compositePipeline.bloomRadiusBuffer,
      0,
      new Float32Array([v])
    );
    this.update();
  }
  get luminosityThreshold() {
    return this._luminosityThreshold;
  }
  set luminosityThreshold(v) {
    this._luminosityThreshold = v;
    Engine.instance.queue.writeBuffer(
      this.luminosityThresholdBuffer,
      0,
      new Float32Array([v])
    );
    this.update();
  }
  get smoothWidth() {
    return this._smoothWidth;
  }
  set smoothWidth(v) {
    this._smoothWidth = v;
    Engine.instance.queue.writeBuffer(
      this.smoothWidthBuffer,
      0,
      new Float32Array([v])
    );
    this.update();
    return this;
  }
  init() {
    // 使用 Map 来存储 bindGroup 缓存
    this.blurBindGroupCache = new Map();
    this.renderTargetsHorizontal = [];
    this.renderTargetsVertical = [];
    this.blurMaterials = [];
    let resx = Math.round(this.resolution.x / 2);
    let resy = Math.round(this.resolution.y / 2);
    // 高亮render targets
    this.brightTexture = Engine.instance.device.createTexture({
      size: [resx, resy],
      format: Engine.instance.format,
      sampleCount: 1,
      usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
    });
    this.brightTexture.id = `UnrealBloomPass.bright`
    this.brightTexture.view = this.brightTexture.createView({ label: "bright texture" })
    this.brightDescript = {
      colorAttachments: [
        {
          view: this.brightTexture.view,
          loadOp: "clear",
          clearValue: { r: 0, g: 0, b: 0, a: 0 },
          storeOp: "store",
        },
      ],
    };
    this.createBrightMaterial()
    // 创建多级模糊纹理
    for (let i = 0; i < this.nMips; i++) {
      // 水平方向的渲染目标
      const horizontalTexture = Engine.instance.device.createTexture({
        size: [resx, resy],
        format: Engine.instance.format,
        usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
      });
      horizontalTexture.id = `UnrealBloomPass.h${i}`
      horizontalTexture.view = horizontalTexture.createView({
        label: `UnrealBloomPass.h${i}`
      });
      this.renderTargetsHorizontal.push(horizontalTexture);
      // 垂直方向的渲染目标
      const verticalTexture = Engine.instance.device.createTexture({
        size: [resx, resy],
        format: Engine.instance.format,
        usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
      });
      verticalTexture.id = `UnrealBloomPass.v${i}`
      verticalTexture.view = verticalTexture.createView({
        label: `UnrealBloomPass.v${i}`
      });
      this.renderTargetsVertical.push(verticalTexture);
      // 创建模糊材质
      this.blurMaterials.push(this.createBlurMaterial(this.kernelSizeArray[i], resx, resy))
      // 降采样尺寸
      resx = Math.round(resx / 2);
      resy = Math.round(resy / 2);
    }
    // composite material
    this.createCompositeMaterial()
    // 创建混和材质
    this.blendTexture = Engine.instance.device.createTexture({
      size: [Engine.instance.size[0], Engine.instance.size[1]],
      format: Engine.instance.format,
      sampleCount: 1,
      usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
    });
    this.blendTexture.id = `UnrealBloomPass.blend`
    this.blendTexture.view = this.blendTexture.createView({ label: "blend texture" })
    const depthTexture = Engine.instance.device.createTexture({
      label: "depth",
      size: Engine.instance.size,
      format: "depth24plus-stencil8",
      mipLevelCount: 1,
      sampleCount: 1,
      usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
    });
    depthTexture.view = depthTexture.createView()
    this.blendDescript = {
      colorAttachments: [
        {
          view: this.blendTexture.view,
          loadOp: "clear",
          clearValue: { r: 0, g: 0, b: 0, a: 0 },
          storeOp: "store",
        },
      ],
      depthStencilAttachment: {
        view: depthTexture.view,
        depthClearValue: 1.0,
        depthLoadOp: "clear",
        depthStoreOp: "store",
        stencilClearValue: 0,
        stencilLoadOp: "clear",
        stencilStoreOp: "store",
      } // 复用主渲染的深度模板附件
    };
    this.createBlendMateria()
  }
  // 辅助方法：计算高斯系数
  calculateGaussianCoefficients(kernelRadius) {
    // ... 计算高斯系数的逻辑
    const coefficients = [];
    for (let i = 0; i < kernelRadius; i++) {
      coefficients.push(0.39894 * Math.exp(- 0.5 * i * i / (kernelRadius * kernelRadius)) / kernelRadius);
    }
    return new Float32Array(coefficients);
  }
  createBrightMaterial() {
    if (!this.brightPipeLine) {
      this.brightPipeLine = Engine.instance.device.createRenderPipeline({
        label: "Bright Pipeline",
        layout: `auto`,
        vertex: {
          module: Engine.instance.device.createShaderModule({
            code: bloom_vert,
          }),
          entryPoint: "main",
        },
        fragment: {
          module: Engine.instance.device.createShaderModule({
            code: bright_frag,
          }),
          entryPoint: "main",
          targets: [
            {
              format: Engine.instance.format,
            },
          ],
        },
        primitive: {
          topology: "triangle-list",
          cullMode: "back",
          frontFace: "ccw",
        },
      });
      this.luminosityThresholdBuffer = Engine.instance.device.createBuffer({
        label: "luminosityThreshold",
        size: 4,
        usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
      });
      this.brightPipeLine.luminosityThresholdBuffer = this.luminosityThresholdBuffer
      this.smoothWidthBuffer = Engine.instance.device.createBuffer({
        label: "smoothWidth",
        size: 4,
        usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
      });
      this.brightPipeLine.smoothWidthBuffer = this.smoothWidthBuffer
    }

  }
  createBlurMaterial(kernelRadius, width, height) {
    // 创建数组存储不同级别的模糊管线
    let blurPipeline = Engine.instance.device.createRenderPipeline({
      label: `Blur Pipeline Level ${kernelRadius}`,
      layout: "auto",
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: bloom_vert,
        }),
        entryPoint: "main",
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: getBlurFragment(kernelRadius),  // 使用不同级别的模糊着色器
        }),
        entryPoint: "main",
        targets: [
          {
            format: Engine.instance.format,
          },
        ],
      },
      primitive: {
        topology: "triangle-list",
        cullMode: "back",
        frontFace: "ccw",
      },
    });
    // invSize buffer
    blurPipeline.invSizeBuffer = Engine.instance.device.createBuffer({
      label: "invSize",
      size: 8,  // vec2 = 2 * float32
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });
    Engine.instance.queue.writeBuffer(
      blurPipeline.invSizeBuffer,
      0,
      new Float32Array([1.0 / width, 1.0 / height])
    );
    // 创建水平和垂直方向的缓冲区
    blurPipeline.horizontalDirectionBuffer = Engine.instance.device.createBuffer({
      label: "horizontal direction",
      size: 8,
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });

    blurPipeline.verticalDirectionBuffer = Engine.instance.device.createBuffer({
      label: "vertical direction",
      size: 8,
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });

    // 预先写入方向值
    Engine.instance.queue.writeBuffer(
      blurPipeline.horizontalDirectionBuffer,
      0,
      new Float32Array([1.0, 0])
    );

    Engine.instance.queue.writeBuffer(
      blurPipeline.verticalDirectionBuffer,
      0,
      new Float32Array([0, 1])
    );
    // 高斯系数
    blurPipeline.kernelSizeBuffer = Engine.instance.device.createBuffer({
      size: 4 * kernelRadius,  // float32 array
      usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,  // 改为 STORAGE
    });
    const gaussianCoefficients = this.calculateGaussianCoefficients(kernelRadius)
    Engine.instance.queue.writeBuffer(
      blurPipeline.kernelSizeBuffer,
      0,
      gaussianCoefficients
    );
    return blurPipeline
  }
  createCompositeMaterial() {
    this.compositePipeline = Engine.instance.device.createRenderPipeline({
      label: `Composite`,
      layout: "auto",
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: bloom_vert,
        }),
        entryPoint: "main",
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: composite_frag,  // 使用不同级别的模糊着色器
        }),
        entryPoint: "main",
        targets: [
          {
            format: Engine.instance.format,
          },
        ],
      },
      primitive: {
        topology: "triangle-list",
        cullMode: "back",
        frontFace: "ccw",
      },
    });
    // 添加 uniform buffers
    this.compositePipeline.bloomStrengthBuffer = Engine.instance.device.createBuffer({
      label: "Bloom Strength Buffer",
      size: 4, // f32 = 4 bytes
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });
    this.compositePipeline.bloomRadiusBuffer = Engine.instance.device.createBuffer({
      label: "Bloom Radius Buffer",
      size: 4, // f32 = 4 bytes
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });
    this.compositePipeline.bloomFactorsBuffer = Engine.instance.device.createBuffer({
      label: "Bloom Factors Buffer",
      size: 5 * 4, // 5 个 f32 = 20 bytes
      usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,  // 改为 STORAGE
    });
    Engine.instance.queue.writeBuffer(
      this.compositePipeline.bloomFactorsBuffer,
      0,
      new Float32Array([1.0, 0.8, 0.6, 0.4, 0.2])
    );
    this.compositePipeline.bloomTintColorsBuffer = Engine.instance.device.createBuffer({
      label: "Bloom Tint Colors Buffer",
      size: 5 * 12, // 5 个 vec3<f32> = 5 * (3 * 4) bytes
      usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,  // 改为 STORAGE
    });
    // 创建tint colors数组 (默认全白色)
    const tintColors = new Float32Array(15); // 5个vec3，总共15个float
    for (let i = 0; i < 5; i++) {
      tintColors[i * 3] = 1.0;     // R
      tintColors[i * 3 + 1] = 1.0; // G
      tintColors[i * 3 + 2] = 1.0; // B
    }
    Engine.instance.queue.writeBuffer(
      this.compositePipeline.bloomTintColorsBuffer,
      0,
      tintColors
    )
  }
  createBlendMateria() {
    this.blendPipeline = Engine.instance.device.createRenderPipeline({
      label: "blendPipeline",
      layout: `auto`,
      vertex: {
        module: Engine.instance.device.createShaderModule({
          code: bloom_vert,
        }),
        entryPoint: "main",
      },
      fragment: {
        module: Engine.instance.device.createShaderModule({
          code: blend_frag,
        }),
        entryPoint: "main",
        targets: [
          {
            format: Engine.instance.format,
            blend: {
              color: {
                operation: 'add',
                srcFactor: 'src-alpha',
                dstFactor: 'one'
              },
              alpha: {
                operation: 'add',
                srcFactor: 'one',
                dstFactor: 'one'
              }
            },
          },
        ],
      },
      depthStencil: {
        format: 'depth24plus-stencil8',
        depthWriteEnabled: false,
        depthCompare: 'always',
      },
      primitive: {
        topology: "triangle-list",
        cullMode: "back",
        frontFace: "ccw",
      },
    });
    this.blendPipeline.opacityBuffer = Engine.instance.device.createBuffer({
      label: "blendPipeline",
      size: 4, // f32 = 4 bytes
      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
    });
    Engine.instance.queue.writeBuffer(
      this.blendPipeline.opacityBuffer,
      0,
      new Float32Array([1.0])
    );
  }
  createMergePipeline() {
    if (!this.mergePipeline) {
      this.mergePipeline = Engine.instance.device.createRenderPipeline({
        label: "Merge Pipeline",
        layout: "auto",
        vertex: {
          module: Engine.instance.device.createShaderModule({
            code: bloom_vert,
          }),
          entryPoint: "main",
        },
        fragment: {
          module: Engine.instance.device.createShaderModule({
            code: merge_frag,  // 需要创建merge_frag着色器
          }),
          entryPoint: "main",
          targets: [{
            format: Engine.instance.format,
          }],
        },
        primitive: {
          topology: "triangle-list",
          cullMode: "back",
          frontFace: "ccw",
        },
      });
    }
  }
  createBightBind(texture) {
    if (this.bightBind && this.bightBind.id != texture.id) {
      this.bightBind = null;
    }
    if (!this.bightBind) {
      this.bightBind = Engine.instance.device.createBindGroup({
        label: "bright group",
        layout: this.brightPipeLine.getBindGroupLayout(0),
        entries: [
          {
            binding: 0,
            resource: texture.view,
          },
          {
            binding: 1,
            resource: this.sampler,
          },
          {
            binding: 2,
            resource: {
              buffer: this.luminosityThresholdBuffer,
              size: 4,
            },
          },
          {
            binding: 3,
            resource: {
              buffer: this.smoothWidthBuffer,
              size: 4,
            },
          },
        ],
      });
      this.bightBind.id = texture.id;
    }
    return this.bightBind;
  }
  createMergeBindGroup(originalTexture) {
    if (this.mergeBindGroup && this.mergeBindGroup.id != originalTexture.id) {
      this.mergeBindGroup = null;
    }
    if (!this.mergeBindGroup) {
      this.mergeBindGroup = Engine.instance.device.createBindGroup({
        label: "merge group",
        layout: this.mergePipeline.getBindGroupLayout(0),
        entries: [
          {
            binding: 0,
            resource: originalTexture.view,
          },
          {
            binding: 1,
            resource: this.blendTexture.view,
          },
          {
            binding: 2,
            resource: this.sampler,
          }
        ],
      });
      this.mergeBindGroup.id = originalTexture.id;
    }
    return this.mergeBindGroup;
  }
  darkenNonBloomed() {
    const meshs = Register.instance.manager(ComponentType.Mesh).components;
    meshs.forEach((mesh, id) => {
      if (!mesh?.shine) {
        const enableDarkerBuffer = mesh.material.getParam("enableDarker");
        if (enableDarkerBuffer) {
          enableDarkerBuffer.buffer(new Float32Array([1]));
        }
      }
    });
  }
  restoreMaterial() {
    const meshs = Register.instance.manager(ComponentType.Mesh).components;
    meshs.forEach((mesh, id) => {
      const enableDarkerBuffer = mesh.material.getParam("enableDarker");
      if (enableDarkerBuffer) {
        if (!mesh?.shine) {
          // 不发光的物体恢复正常
          enableDarkerBuffer.buffer(new Float32Array([0]));
        }
      }
    });
  }
  // 在 createBlurBindGroup 中根据方向使用不同的缓冲区
  createBlurBindGroup(inputTexture, blurPipeline, isHorizontal = true) {
    const cacheKey = `${inputTexture.id}_${blurPipeline.label}_${isHorizontal}`;

    if (this.blurBindGroupCache.has(cacheKey)) {
      return this.blurBindGroupCache.get(cacheKey);
    }

    const bindGroup = Engine.instance.device.createBindGroup({
      layout: blurPipeline.getBindGroupLayout(0),
      entries: [
        {
          binding: 0,
          resource: inputTexture.view
        },
        {
          binding: 1,
          resource: this.sampler
        },
        {
          binding: 2,
          resource: { buffer: blurPipeline.invSizeBuffer }
        },
        {
          binding: 3,
          resource: {
            buffer: isHorizontal ?
              blurPipeline.horizontalDirectionBuffer :
              blurPipeline.verticalDirectionBuffer
          }
        },
        {
          binding: 4,
          resource: { buffer: blurPipeline.kernelSizeBuffer }
        }
      ]
    });

    this.blurBindGroupCache.set(cacheKey, bindGroup);
    return bindGroup;
  }
  createCompositeBindGroup(texture0, texture1, texture2, texture3, texture4, pipeline) {
    // 使用纹理ID创建唯一的缓存键
    const cacheKey = `${texture0.id}_${texture1.id}_${texture2.id}_${texture3.id}_${texture4.id}`;

    // 检查缓存中是否已存在
    if (this.compositeBindGroup && this.compositeBindGroup.cacheKey === cacheKey) {
      return this.compositeBindGroup;
    }

    // 创建新的 bindGroup
    this.compositeBindGroup = Engine.instance.device.createBindGroup({
      layout: pipeline.getBindGroupLayout(0),
      entries: [
        {
          binding: 0,
          resource: texture0.view
        },
        {
          binding: 1,
          resource: texture1.view
        },
        {
          binding: 2,
          resource: texture2.view
        },
        {
          binding: 3,
          resource: texture3.view
        },
        {
          binding: 4,
          resource: texture4.view
        },
        {
          binding: 5,
          resource: this.sampler
        },
        {
          binding: 6,
          resource: {
            buffer: pipeline.bloomStrengthBuffer
          }
        },
        {
          binding: 7,
          resource: {
            buffer: pipeline.bloomRadiusBuffer
          }
        },
        {
          binding: 8,
          resource: {
            buffer: pipeline.bloomFactorsBuffer
          }
        },
        {
          binding: 9,
          resource: {
            buffer: pipeline.bloomTintColorsBuffer
          }
        }
      ]
    });

    // 存储缓存键
    this.compositeBindGroup.cacheKey = cacheKey;

    return this.compositeBindGroup;
  }
  createBlendBindGroup(texture) {
    // 如果已存在 bindGroup 且纹理 ID 相同，直接返回缓存的 bindGroup
    if (this.blendBindGroup && this.blendBindGroup.id === texture.id) {
      return this.blendBindGroup;
    }
    // 创建新的 bindGroup
    this.blendBindGroup = Engine.instance.device.createBindGroup({
      label: "blend group",
      layout: this.blendPipeline.getBindGroupLayout(0),
      entries: [
        {
          binding: 0,
          resource: texture.view,
        },
        {
          binding: 1,
          resource: this.sampler,
        },
        {
          binding: 2,
          resource: {
            buffer: this.blendPipeline.opacityBuffer,
          },
        },
      ],
    });

    // 缓存纹理 ID
    this.blendBindGroup.id = texture.id;

    return this.blendBindGroup;
  }
  onRender(commandEncoder) {
    // 1. 设置材质状态（发光物体正常显示，非发光物体变黑）
    this.darkenNonBloomed();
    // 2. 渲染到 shine 纹理（此时应该只有发光物体有颜色）
    let commandEncoderShine = Engine.instance.device.createCommandEncoder();
    const ShineDescript = this.getShineDescript();
    const meshRednerCom = Register.instance.manager(ComponentType.MeshRender).get("x");
    const bundles = meshRednerCom.bundles;
    const renderPassShine = commandEncoderShine.beginRenderPass(ShineDescript);
    renderPassShine.executeBundles(bundles);
    renderPassShine.end();
    // 3. 提取亮度
    if (!this.shineTexture || this.blurMaterials.length == 0) return;
    const renderPass = commandEncoderShine.beginRenderPass(this.brightDescript);
    renderPass.setPipeline(this.brightPipeLine);
    let bindGroup = this.createBightBind(this.shineTexture)
    renderPass.setBindGroup(0, bindGroup);
    renderPass.draw(3);
    renderPass.end();
    // 4. 模糊
    let inputTexture = this.brightTexture;  // 初始输入是亮度纹理
    for (let i = 0; i < this.nMips; i++) {
      let blurPipeline = this.blurMaterials[i]
      // 1. 水平方向模糊
      Engine.instance.queue.writeBuffer(
        blurPipeline.horizontalDirectionBuffer,
        0,
        new Float32Array([1.0, 0])
      );
      const horizontalTexture = this.renderTargetsHorizontal[i]
      let horizontalDescript = {
        colorAttachments: [
          {
            view: horizontalTexture.view,
            loadOp: "clear",
            clearValue: { r: 0, g: 0, b: 0, a: 0 },
            storeOp: "store",
          },
        ],
      };
      const renderPassHorizontal = commandEncoderShine.beginRenderPass(horizontalDescript);
      renderPassHorizontal.setPipeline(blurPipeline);
      let horizontalBindGroup = this.createBlurBindGroup(inputTexture, blurPipeline, true);
      renderPassHorizontal.setBindGroup(0, horizontalBindGroup);
      renderPassHorizontal.draw(3);
      renderPassHorizontal.end();
      // 2. 垂直方向模糊
      Engine.instance.queue.writeBuffer(
        blurPipeline.verticalDirectionBuffer,
        0,
        new Float32Array([0, 1])
      );
      const verticalTexture = this.renderTargetsVertical[i]
      let verticalDescript = {
        colorAttachments: [
          {
            view: verticalTexture.view,
            loadOp: "clear",
            clearValue: { r: 0, g: 0, b: 0, a: 0 },
            storeOp: "store",
          },
        ],
      };
      const renderPassVertical = commandEncoderShine.beginRenderPass(verticalDescript);
      renderPassVertical.setPipeline(blurPipeline);
      let verticalBindGroup = this.createBlurBindGroup(this.renderTargetsHorizontal[i], blurPipeline, false);
      renderPassVertical.setBindGroup(0, verticalBindGroup);
      renderPassVertical.draw(3);
      renderPassVertical.end();
      // 更新输入纹理为当前级别的垂直模糊结果
      inputTexture = this.renderTargetsVertical[i];
    }
    // 复合所有mipmap
    const compositeTexture = this.renderTargetsHorizontal[0]
    const compositeDescript = {
      colorAttachments: [
        {
          view: compositeTexture.view,
          loadOp: "clear",
          clearValue: { r: 0, g: 0, b: 0, a: 0 },
          storeOp: "store",
        },
      ],
    };
    const renderPassComposite = commandEncoderShine.beginRenderPass(compositeDescript);
    renderPassComposite.setPipeline(this.compositePipeline);
    let compositeBindGroup = this.createCompositeBindGroup(
      this.renderTargetsVertical[0],
      this.renderTargetsVertical[1],
      this.renderTargetsVertical[2],
      this.renderTargetsVertical[3],
      this.renderTargetsVertical[4],
      this.compositePipeline);
    renderPassComposite.setBindGroup(0, compositeBindGroup);
    renderPassComposite.draw(3);
    renderPassComposite.end();
    // 混和
    const renderPassBlend = commandEncoderShine.beginRenderPass(this.blendDescript);
    renderPassBlend.setPipeline(this.blendPipeline);
    let blendBindGroup = this.createBlendBindGroup(this.renderTargetsHorizontal[0]);
    renderPassBlend.setBindGroup(0, blendBindGroup);
    renderPassBlend.draw(3);
    renderPassBlend.end();
    Engine.instance.device.queue.submit([commandEncoderShine.finish()]);

    // 5. 恢复所有物体的正常显示
    this.restoreMaterial();
    // 6. 合并原始场景和发光效果
    const pass = super.onRender(commandEncoder);
    const renderPassMerge = commandEncoder.beginRenderPass(pass);
    renderPassMerge.setPipeline(this.mergePipeline);
    const texture = Pass.instance().readAttach;
    const mergeBindGroup = this.createMergeBindGroup(texture);
    renderPassMerge.setBindGroup(0, mergeBindGroup);
    renderPassMerge.draw(3);
    renderPassMerge.end();
  }

  getShineDescript() {
    if (!this.shineTexture ||
      this.shineTexture.width !== Engine.instance.size[0] ||
      this.shineTexture.height !== Engine.instance.size[1]) {
      // 创建发光颜色附件
      this.shineTexture = Engine.instance.device.createTexture({
        size: [Engine.instance.size[0], Engine.instance.size[1]],
        format: Engine.instance.format,
        sampleCount: 1,
        usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING
      });
      this.shineTexture.view = this.shineTexture.createView({ label: "shine texture" })
      this.shineTexture.id = `shineTexture_${Engine.instance.size[0]}_${Engine.instance.size[1]}`
      this.shineDescript = {
        colorAttachments: [
          {
            view: Pass.instance().colorTexture.view,
            resolveTarget: this.shineTexture.view,
            loadOp: "clear",
            clearValue: { r: 0, g: 0, b: 0, a: 0 },
            storeOp: "store",
          },
        ],
        depthStencilAttachment: {
          view: Pass.instance().depthAttach.view,
          depthClearValue: 1.0,
          depthLoadOp: "clear",
          depthStoreOp: "store",
          stencilClearValue: 0,
          stencilLoadOp: "clear",
          stencilStoreOp: "store",
        } // 复用主渲染的深度模板附件
      };
      // 如果开启了GBuffer,添加position和normal附件
      if (Engine.instance.enableGbuffer) {
        this.shineDescript.colorAttachments.push({
          label: "position",
          view: Pass.instance().postionAttach.view,
          loadOp: "clear",
          clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 0 },
          storeOp: "store"
        });
        this.shineDescript.colorAttachments.push({
          label: "normal",
          view: Pass.instance().normalAttach.view,
          loadOp: "clear",
          clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 0 },
          storeOp: "store"
        });
      }
      // 如果开启了拾取功能,添加pick附件
      if (Engine.instance.enablePick) {
        this.shineDescript.colorAttachments.push({
          label: "pick",
          view: Pass.instance().pickAttach.view,
          loadOp: "clear",
          clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 0 },
          storeOp: "store"
        });
      }
    }
    return this.shineDescript;
  }
  getDescript() {
    if (this._descript) {
      if (
        this._descript.size[0] !== Engine.instance.size[0] ||
        this._descript.size[1] !== Engine.instance.size[1]
      ) {
        this._descript = null;
      } else {
        this._descript.colorAttachments[0].view =
          Pass.instance().writeAttach.view;
      }
    }
    if (!this._descript) {
      this._descript = {
        colorAttachments: [
          {
            view: Pass.instance().writeAttach.view,
            loadOp: "clear",
            clearValue: { r: 1.0, g: 1.0, b: 1.0, a: 1.0 },
            storeOp: "store",
          },
        ],
      };
      this._descript.size = Engine.instance.size;
    }
    return this._descript;
  }
}
export { Bloom };
